﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class GameManager : MonoBehaviour
{
    private static GameManager _instance;

    public static GameManager Instance
    {
        get => _instance;
        set => _instance = value;
    }
    //定义长宽 length长 row宽
    public int length;
    public int Row;
    public float waittime;
    public GameObject gridpre;//格子
    public Text timeTex;
    private float time;
    bool gameover;
    public Text ScoreText;
    public Text FinScoreText; 
    public int Score;
    public GameObject gameoverpre;
    #region 甜品
    //种类
    public enum SweetsType
    {
        EMPTY,//空
        NORMAL,//正常
        BARRIER,//阻碍
        ROWCLEAR,//列消除
        LENGTHCLEAR,//行消除
        RAINBOWCANDY,//彩虹糖
        COUNT//标记类型
    }
    //预制体字典 通过种类来得到物品 字典public也不能出现在面板
    public Dictionary<SweetsType, GameObject> sweetsPreDic;

    [System.Serializable]//可以使结构体出现在面板（序列化）
    public struct SweetPrefab
    {
        public SweetsType type;
        public GameObject sweetprefab;
    }
    public SweetPrefab[] sweetPrefabs;
    #endregion 甜品

    //甜品生成位置数组
    private Gamesweet[,] sweets;
    void Awake()
    {
        _instance = this;
        time = 60;
    }
    private void Update()
    {
        if (gameover) return; 
        time -= Time.deltaTime; 
        timeTex.text = time.ToString("0");
        ScoreText.text = Score.ToString("0");
        FinScoreText.text = Score.ToString("0");

        if (time <= 0)
        {
            time = 0;
            gameoverpre.SetActive(true);
            gameover = true;
        }
    }
    private void Start()
    {
        //实例化字典
        sweetsPreDic = new Dictionary<SweetsType, GameObject>();
        for(int index=0;index<sweetPrefabs.Length;index++)
        {
            if(!sweetsPreDic.ContainsKey(sweetPrefabs[index].type))
            {
                sweetsPreDic.Add(sweetPrefabs[index].type, sweetPrefabs[index].sweetprefab);//若字典中没有该键值对 就将其添加
            }
        }
        //实例化糖果数组
        sweets = new Gamesweet[length,Row];
        //生成空
        for (int index = 0; index < length; index++)
        {
            for (int indexk = 0; indexk < Row; indexk++)
            {
                CreatnewSweet(index, indexk, SweetsType.EMPTY);
                //if (sweets[index, indexk].Can_color())
                //{
                //    sweets[index, indexk].ColorComponent.SetColor((ColorSweet.ColorType)(Random.Range(0, sweets[index, indexk].ColorComponent.NumClolrs))); //测试是否可以变色
                //}
            }
        }

        //生成格子
        for (int index=0;index<length;index++)
        {
            for(int indexk = 0; indexk < Row; indexk++)
            {
                GameObject gezi = Instantiate(gridpre, reset_pos(index,indexk), Quaternion.identity);
                gezi.transform.SetParent(GameObject.Find("GameManager").transform,true);
                gezi.name = "格子";
            }
        }
        // 生成障碍物
        Destroy(sweets[4, 4].gameObject);
        CreatnewSweet(4,4,SweetsType.BARRIER);
        StartCoroutine(AllFill());
    }
    public Vector2 reset_pos(float x, float y)
    {
        x += transform.position.x - length / 2;
        y = transform.position.y + Row / 2-y;
        return new Vector2 (x,y);
    } 
    //产生甜品
    public Gamesweet CreatnewSweet(int x,int y,SweetsType sweetsType)
    {
       GameObject newsweet= Instantiate(sweetsPreDic[sweetsType], reset_pos(x, y), Quaternion.identity);
        newsweet.transform.SetParent(GameObject.Find("GameManager").transform);
        sweets[x, y] = newsweet.GetComponent<Gamesweet>();
        sweets[x, y].Init(x, y, this, sweetsType);
        newsweet.name = x + " " + y;
        return sweets[x, y];
    }

    #region 填充
    public IEnumerator AllFill()//全部填充
    {
        bool needRefill = true;//是否需要填充
        while (needRefill)
        {
            yield return new WaitForSeconds(waittime); 
            while (Fill())
            {
                yield return new WaitForSeconds(waittime);
            }
            needRefill = Clear_All();
        }
    }
    public bool Fill()//分部填充
    {
        //算法思路：从上往下掉，若最上层也掉了，就重新生成甜品

        bool filledNotFinshed = false;//是否填充完成 默认完成


        //最上排为空就新生成甜品
        for (int index = 0; index < length; index++)
        {
            Gamesweet sweet = sweets[index, 0];
            sweet.name = "new";
            if (sweet.Type1 == SweetsType.EMPTY)
            {
                GameObject newsweet = Instantiate(sweetsPreDic[SweetsType.NORMAL], reset_pos(index, -1), Quaternion.identity);
                newsweet.transform.SetParent(GameObject.Find("GameManager").transform);
                sweets[index, 0] = newsweet.GetComponent<Gamesweet>();
                sweets[index, 0].Init(index, -1, this, SweetsType.NORMAL);
                sweets[index, 0].Canmove.Move(index, 0, waittime);
                sweets[index, 0].ColorComponent.SetColor((ColorSweet.ColorType)Random.Range(1, sweets[index, 0].ColorComponent.NumClolrs));
                filledNotFinshed = true;
            }
        }

        for (int index = Row - 2; index >= 0; index--)//竖着判断，从下往上判断是否为空 若为空则数组下移
        {
            for (int index_1 = 0; index_1 < length; index_1++)
            {
                Gamesweet sweet = sweets[index_1, index];//得到当前元素的位置
                if (sweet.Can_move())//可以移动,垂直填充
                {
                    Gamesweet oldsweet = sweets[index_1, index + 1];
                    if (oldsweet.Type1 == SweetsType.EMPTY)
                    {
                        Destroy(oldsweet.gameObject);
                        sweet.Canmove.Move(index_1, index + 1, waittime);
                        sweets[index_1, index + 1] = sweet;
                        CreatnewSweet(index_1, index, SweetsType.EMPTY);
                        filledNotFinshed = true;
                    }
                    //左下右下填充
                    else
                    {
                        for (int down = -1; down <= 1; down++)//-1左下 0正下方 1正下
                        {
                            if (down != 0)
                            {
                                int downx = down + index_1;
                                if (downx >= 0 && downx < length)//排除左右边界
                                {
                                    Gamesweet downsweet = sweets[downx, index + 1];
                                    if (downsweet.Type1 == SweetsType.EMPTY)
                                    {
                                        bool canfill = true;//是否可以垂直填充
                                        for (int aboveY = index; aboveY >= 0; aboveY--)
                                        {
                                            Gamesweet abovesweet = sweets[downx, aboveY];
                                            if (abovesweet.Can_move())
                                                break;
                                            else if (!abovesweet.Can_move() && abovesweet.Type1 != SweetsType.EMPTY)//斜向填充
                                            {
                                                canfill = false;
                                                break;
                                            }
                                        }
                                        if (!canfill)
                                        {
                                            Destroy(downsweet.gameObject);
                                            sweet.Canmove.Move(downx, index + 1, waittime);
                                            sweets[downx, index + 1] = sweet;
                                            CreatnewSweet(index_1, index, SweetsType.EMPTY);
                                            filledNotFinshed = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } 
        return filledNotFinshed;
    }
    #endregion 填充

    public bool IsFriend(Gamesweet sweet1, Gamesweet sweet2)//判断是否相邻
    {
        return (sweet1.X == sweet2.X && Mathf.Abs(sweet1.Y - sweet2.Y) == 1) || (sweet1.Y == sweet2.Y && Mathf.Abs(sweet1.X - sweet2.X) == 1);
    }
    private void ChangeSweet(Gamesweet sweet1, Gamesweet sweet2)//拖拽移动
    {
        if (sweet1.Can_move() && sweet2.Can_move())
        {
            sweets[sweet1.X, sweet1.Y] = sweet2;
            sweets[sweet2.X, sweet2.Y] = sweet1;
            if (MatchSweets(sweet1, sweet2.X, sweet2.Y) != null || MatchSweets(sweet2, sweet1.X, sweet1.Y) != null)
            {
                int tempx = sweet1.X;
                int tempy = sweet1.Y;
                sweet1.Canmove.Move(sweet2.X, sweet2.Y, waittime);
                sweet2.Canmove.Move(tempx, tempy, waittime);
                Clear_All();
                StartCoroutine(AllFill());
            }
            else
            {
                sweets[sweet1.X, sweet1.Y] = sweet1;
                sweets[sweet2.X, sweet2.Y] = sweet2;
            }
        }
    }
    //交换的对象
    private Gamesweet sweet1,sweet2;
    public void PressSweet(Gamesweet sweet)
    {
        if (gameover) return;
        sweet1 = sweet;
        
    }
    public void EnterSweet(Gamesweet sweet)
    {
        if (gameover) return;
        sweet2 = sweet;
    }
    public void ReleaseSweet(Gamesweet sweet)
    {
        if (gameover) return;
        if (IsFriend(sweet1, sweet2))
        {
            ChangeSweet(sweet1, sweet2);
        }
    }
    //匹配
    public List<Gamesweet> MatchSweets(Gamesweet sweet, int newX, int newY)
    {
        if(sweet.Can_color())
        {
            ColorSweet.ColorType color = sweet.ColorComponent.Color;
            List<Gamesweet> matchRowSweets = new List<Gamesweet>();
            List<Gamesweet> matchLenthSweets = new List<Gamesweet>();
            List<Gamesweet> finishedSweets = new List<Gamesweet>();
            //行匹配
            matchLenthSweets.Add(sweet);
            for(int index=0;index<=1;index++)//0 向左 1 向右
            {
                for(int xDistance=1;xDistance<length;xDistance++)
                {
                    int x;
                    if(index==0)
                    {
                        //左遍历
                        x = newX - xDistance;
                    }
                    else
                    {
                        //右遍历
                        x = newX + xDistance;
                    }
                    if (x < 0 || x >= length) break;//超过边界
                    if (sweets[x, newY].Can_color() && sweets[x, newY].ColorComponent.Color == color)
                    {
                        matchLenthSweets.Add(sweets[x, newY]);
                    }
                    else break;
                }
            }
            if(matchLenthSweets.Count>=3)
            {
                for (int index = 0; index < matchLenthSweets.Count; index++)
                {
                    finishedSweets.Add(matchLenthSweets[index]); 
                    for (int row = 0; row <= 1; row++)//0 向上 1 向下
                    {
                        for (int yDistance = 1; yDistance < length; yDistance++)
                        {
                            int y;
                            if (index == 0)
                            {
                                //下遍历
                                y = newY - yDistance;
                            }
                            else
                            {
                                //上遍历
                                y = newY + yDistance;
                            }
                            if (y < 0 || y >=Row) break;//超过边界
                            if (sweets[matchLenthSweets[index].X, y].Can_color() && sweets[matchLenthSweets[index].X, y].ColorComponent.Color == color)
                            {
                                matchRowSweets.Add(sweets[matchLenthSweets[index].X, y]);
                            }
                            else break;
                        }
                    } 
                    for (int index_save = 0; index_save < matchRowSweets.Count; index_save++)
                        finishedSweets.Add(matchRowSweets[index_save]);  

                }
            }
            if (finishedSweets.Count >= 3)
            { return finishedSweets; }
            if (finishedSweets.Count < 3)
            {
                finishedSweets.Clear();
                matchRowSweets.Clear();
                matchLenthSweets.Clear();
            }
            //列匹配
            matchRowSweets.Add(sweet);
            for (int index = 0; index <= 1; index++)//0 向左 1 向右
            {
                for (int yDistance = 1; yDistance < length; yDistance++)
                {
                    int y;
                    if (index == 0)
                    {
                        //下遍历
                        y = newY - yDistance;
                    }
                    else
                    {
                        //上遍历
                        y = newY + yDistance;
                    }
                    if (y < 0 || y >= length) break;//超过边界
                    if (sweets[newX, y].Can_color() && sweets[newX, y].ColorComponent.Color == color)
                    {
                        matchRowSweets.Add(sweets[newX, y]);
                    }
                    else break;
                }
            }
            if (matchRowSweets.Count >= 3)
            {
                for (int index = 0; index < matchRowSweets.Count; index++)
                {
                    finishedSweets.Add(matchRowSweets[index]);
                    for (int len=0;len<2;len++)
                    {
                        for(int xDic=1;xDic<length;xDic++)
                        {
                            int x;
                            if (index == 0)
                            {
                                //左遍历
                                x = newX - xDic;
                            }
                            else
                            {
                                //右遍历
                                x = newX + xDic;
                            }
                            if (x < 0 || x >= length) break;//超过边界
                            if (sweets[x,matchRowSweets[index].Y ].Can_color() && sweets[x, matchRowSweets[index].Y].ColorComponent.Color == color)
                            {
                                matchLenthSweets.Add(sweets[x, matchRowSweets[index].Y]);
                            }
                            else break;
                        }
                    }
                    for (int index_len = 0; index_len < matchLenthSweets.Count; index_len++)
                        finishedSweets.Add(matchLenthSweets[index_len]);
                }
            }
            if (finishedSweets.Count >= 3)
            { return finishedSweets; }
            if (finishedSweets.Count < 3)
            {
                finishedSweets.Clear();
                matchRowSweets.Clear();
                matchLenthSweets.Clear();
            }
        }
        return null;
    }
    /// <summary>
    /// 清除糖果
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    /// <returns></returns>
    public bool Clear(int x,int y)
    {
        if (sweets[x, y].Can_clear() && !sweets[x, y].ClearComponent.Isclear)
        {
            sweets[x, y].ClearComponent.Clear();
            CreatnewSweet(x, y, SweetsType.EMPTY);
            Clear_binggan(x, y);
            return true;
        }
        else return false;
    }
    /// <summary>
    /// 清除所有甜品
    /// </summary>
    public bool Clear_All()
    {
        bool needRefill = false;//是否需要重新填充
        for(int index_y=0;index_y<Row;index_y++)
        {
            for (int index_x = 0; index_x < length; index_x++)
            {
                if(sweets[index_x,index_y].Can_clear())
                {
                    List<Gamesweet> sweetList = MatchSweets(sweets[index_x, index_y], index_x, index_y);
                    if (sweetList!=null)
                    {
                        SweetsType specialSweetType = SweetsType.COUNT;
                        Gamesweet randomSweet = sweetList[Random.Range(0, sweetList.Count)];
                        int specialX = randomSweet.X;
                        int specialY = randomSweet.Y;
                        if(sweetList.Count==4)
                        {
                            specialSweetType = (SweetsType)Random.Range((int)SweetsType.LENGTHCLEAR, (int)SweetsType.ROWCLEAR);
                        }
 
                        for (int index=0;index<sweetList.Count;index++)
                        {
                            if (Clear(sweetList[index].X, sweetList[index].Y))
                                needRefill = true;
                        }
                        ///生成特殊甜品
                        if(specialSweetType!=SweetsType.COUNT)
                        {
                            Destroy(sweets[specialX, specialY]);
                            Gamesweet newsweet = CreatnewSweet(specialX, specialY, specialSweetType);
                            //if (specialSweetType == SweetsType.ROWCLEAR || specialSweetType == SweetsType.LENGTHCLEAR && newsweet.Can_clear()&& sweetList[0].Can_color())
                            //    newsweet.ColorComponent.SetColor(sweetList[0].ColorComponent.Color);
                        }
                    }
                }
            }
        }
        return needRefill;
    }
    /// <summary>
    /// 清除饼干
    /// </summary>
    public void Clear_binggan(int x,int y)
    {
        for(int fienx=x-1;fienx<=x+1;fienx++)
        {
            if(fienx != x&&fienx>0&&fienx<length)
            {
                if(sweets[x,y].Type1==SweetsType.BARRIER&&sweets[fienx, y].Can_clear())
                {
                    sweets[fienx, y].ClearComponent.Clear();
                    CreatnewSweet(fienx, y, SweetsType.EMPTY);
                }
            }
        }
        for (int fieny = y - 1; fieny <= y + 1; fieny++)
        {
            if (fieny != y&&fieny > 0 && fieny< Row)
            {
                if (sweets[x, y].Type1 == SweetsType.BARRIER && sweets[x, fieny].Can_clear())
                {
                    sweets[x, fieny].ClearComponent.Clear();
                    CreatnewSweet(x, fieny, SweetsType.EMPTY);
                }
            }
        }
    }
    /// <summary>
    /// 返回主界面
    /// </summary>
    public void back()
    {
        SceneManager.LoadScene(0);
    }
    public void replace()
    {
        SceneManager.LoadScene(1);
    }
    /// <summary>
    /// 整行整列消除
    /// </summary>
    /// <param name="x"></param>
    public void Clear_Row(int x)
    {
        for(int index=0;index<Row;index++)
        {
            Clear(x, index);
        }
    }
    public void Clear_Length(int y)
    {
        for (int index = 0; index < length; index++)
        {
            Clear(index, y);
        }
    }
}
